# -*- coding: utf-8 -*-
from Kits import Kits
import time
from multiprocessing import Pool,Process,Manager
import os
import requests
from itertools import repeat
import sys
import logging
logger = logging.getLogger('print')

out_put = sys.stdout

class Download:
    version = 1.0
    def __init__(self):
        self.artist_length = Kits.get_artist_name_length(Kits)
        self.path         = Kits.dir_created(Kits)


    @staticmethod
    def connect(url):
        return requests.session().get(url,timeout = 15)

    def single_download(self,args):
        """
        参数：args：携带单个网址和一个用于插入下载成功文件的列表
        功能：执行单次下载
        模块解释：除了使用文件创建和requests请求之外，还有一些问题的对应处理：
                网络波动引起的文件下载不完整（使用响应头中的信息判断大小并和本地文件比较，不同则视为下载失败）
                文件为图片文件之外的，通过content-type判断类型或检测文件名是否合法，采取不同的名称截断策略
        """
        time.sleep(0.5)
        results,list_share = args
        logger.debug(results)
        AL = self.artist_length
        Startline = AL + 43
        Startline_for_long = AL + 60
        size = 0                                             #确保size永远有定义

        try:
            source = Download.connect(results)
            file_type = source.headers["content-type"]
        except requests.exceptions.RequestException:
            logger.warning("Timeout")
            return

        if not source.status_code == 200:
            logger.warning("Connect error %s"%(results))
            return

        if not '/' in results[Startline:]:
            file_path = self.path + '%s'%(results[Startline:])
            size   = source.headers["Content-Length"]           #目标文件大小

        else:
            file_path = self.path + '%s'%(results[Startline_for_long:])
            list_share.append(results)

        with open(file_path, 'wb') as dest:
            dest.write(source.content)
        if file_type == "text/plain":
            return

        file_size = os.path.getsize(file_path)              #实际文件大小

        if file_size == int(size) and file_size != 0:
            list_share.append(results)

        else:                                               #大小不匹配，则重新下载
            logger.warning("Size difference! goal:%d Downloaded:%d url:%s"%(int(size),file_size,results))


    def processing_bar(self,args):
        now,total = args
        while True:
            sys.stdout.write(u'\rProcessing percent %d / %d:'%(len(now),total))
            sys.stdout.flush()
            if len(now) == total:
                return
            time.sleep(0.5)

    def multi_download(self,list_result):
        '''参数：list_result：携带图片网址列表
           功能：多进程下载
           模块返回：list_share: 下载成功的网址
        '''
        #processing = Manager().list()
        list_share = Manager().list()
        list_total = len(list_result)
        data = zip(list_result,repeat(list_share))

        logger.info('Amount of to-be downloaded urls: ' + str(list_total))
        #vice_Processing = Process(target = self.processing_bar,args = ((list_share,list_total),))

        #vice_Processing.start()
        workers = Pool(8)
        workers.map(self.single_download,data)
        workers.close()
        workers.join()
        return list_share
